package com.bmps.springcloud.insuredmicroservice.controller.accept;

import com.alibaba.fastjson.JSONObject;
import com.bmps.springcloud.common.response.TaskResponseModel;
import com.bmps.springcloud.common.task.TaskExecutor;
import com.bmps.springcloud.common.task.bean.RequestObject;
import com.bmps.springcloud.insuredmicroservice.callback.accept.BlackCustomerCallBack;
import com.bmps.springcloud.insuredmicroservice.constant.accept.AcceptConstant;
import com.bmps.springcloud.insuredmicroservice.constant.accept.DigitalConstant;
import com.bmps.springcloud.insuredmicroservice.constant.accept.MultConstant;
import com.bmps.springcloud.insuredmicroservice.constant.accept.QuotaConstant;
import com.bmps.springcloud.insuredmicroservice.model.accept.MessageModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.PersonModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.PolicyModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.RequestInfoModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.response.AcceptResponseDataModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.response.ResponseModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.response.ResultModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.resquest.*;
import com.bmps.springcloud.insuredmicroservice.model.rabbitmq.RabbitPolicyModel;
import com.bmps.springcloud.insuredmicroservice.service.RedisService;
import com.bmps.springcloud.insuredmicroservice.service.accept.AcceptBlackCustomerService;
import com.bmps.springcloud.insuredmicroservice.service.accept.InsuranceAcceptCoreService;
import com.bmps.springcloud.insuredmicroservice.service.accept.InsuranceAcceptService;
import com.bmps.springcloud.insuredmicroservice.service.rabbitmq.production.AcceptProducerService;
import com.bmps.springcloud.insuredmicroservice.util.accept.AcceptUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

/**
 * @author lyw
 * @date 2019/07/24
 */
@RestController
@RequestMapping(value = "/insured")
public class InsuranceAcceptController {

    private static Logger logger = LoggerFactory.getLogger(InsuranceAcceptController.class);

    private final TaskExecutor taskExecutor;

    private final RedisService redisService;

    private final InsuranceAcceptService insuranceAcceptService;

    private final AcceptBlackCustomerService acceptBlackCustomerService;

    private final ExecuteConcurrentBatchTask executeConcurrentBatchTask;

    private final InsuranceAcceptCoreService insuranceAcceptCoreService;

    private final AcceptProducerService acceptProducerService;

    public InsuranceAcceptController(TaskExecutor taskExecutor,
                                     RedisService redisService,
                                     InsuranceAcceptService insuranceAcceptService,
                                     ExecuteConcurrentBatchTask executeConcurrentBatchTask,
                                     AcceptBlackCustomerService acceptBlackCustomerService,
                                     InsuranceAcceptCoreService insuranceAcceptCoreService,
                                     AcceptProducerService acceptProducerService) {
        this.taskExecutor = taskExecutor;
        this.redisService = redisService;
        this.insuranceAcceptService = insuranceAcceptService;
        this.executeConcurrentBatchTask = executeConcurrentBatchTask;
        this.acceptBlackCustomerService = acceptBlackCustomerService;
        this.insuranceAcceptCoreService = insuranceAcceptCoreService;
        this.acceptProducerService = acceptProducerService;
    }


    @PostMapping(value = "/acceptpolicy", headers = "Content-Type=application/json;charset=UTF-8")
    public AcceptResponseDataModel acceptPolicy(@Valid @RequestBody AcceptRequestDataModel acceptRequestDataModel,
                                                BindingResult bindingResult) {
        logger.info("【参数】" + acceptRequestDataModel.toString());
        long start = System.currentTimeMillis();
        //校验参数是否符合设定的规则，如果不符合，返回
        if (bindingResult.hasErrors()) {
            return InsuranceAcceptSupport.bindingErrors(acceptRequestDataModel.getHeader(), bindingResult);
        }
        ResultModel optional = this.optionalCheck(acceptRequestDataModel.getRequest());
        if (optional != null) {
            return AcceptUtil.getResponseResult(acceptRequestDataModel.getHeader(), optional, null);
        }
        //校验报文中是否存在不支持的产品以及是否缺失主险
        List<ProductModel> productListModel = acceptRequestDataModel.getRequest().getProductInfo().getProducts().getProduct();
        AcceptResponseDataModel acceptResponseDataModel = hasSupportAndMainRisk(productListModel, acceptRequestDataModel);
        if (!acceptResponseDataModel.getFlag()) {
            return acceptResponseDataModel;
        }
        //校验产品有效期
        //String verify = verifyRiskCodePeriod(acceptRequestDataModel);
        // if (StringUtils.isNotBlank(verify)) {
        //     return AcceptUtil.getResponseResult(acceptRequestDataModel.getHeader(), new ResultModel(AcceptConstant.RESULT_FAIL_CODE, verify), null);
        // }
        //1.业务逻辑黑名单
        // acceptResponseDataModel = isCustomerBlackList(acceptRequestDataModel.getRequest().getCustInfo(),
        //         acceptRequestDataModel.getHeader());
        // if (!acceptResponseDataModel.getFlag()) {
        //     return messageStorageError(acceptResponseDataModel, acceptRequestDataModel, start);
        // }
        //2.准备投被保人客户号以及黑名单 理赔标识 白名单标识
        // acceptResponseDataModel = setCustomerNo(acceptRequestDataModel);
        // if (!acceptResponseDataModel.getFlag()) {
        //     return messageStorageError(acceptResponseDataModel, acceptRequestDataModel, start);
        // }
        //3.获取调用保盾云的人员列表
        //4.添加并发任务  --投核保   累计风险保额(新客户)   保费试算  (并发Concurrency)  保盾云  核保在途保单校验任务
        acceptResponseDataModel = executeConcurrentBatchTask.executeConcurrentTask(acceptRequestDataModel);
        if (!acceptResponseDataModel.getFlag()) {
            // 受理失败，删除Redis中的该保单的累计风险保额缓存
            redisService.delDim("*|" + acceptRequestDataModel.getRequest().getPolicyInfo().getContNo() + "|" + QuotaConstant.QUOTA);
            // 受理失败，删除Redis中的该保单的购买份数
            redisService.delDim("*|" + acceptRequestDataModel.getRequest().getPolicyInfo().getContNo() + "|" + "*|" + MultConstant.MULT);
            return messageStorageError(acceptResponseDataModel, acceptRequestDataModel, start);
        }
        return messageStorageSuccess(acceptResponseDataModel, acceptRequestDataModel, start);
    }

    private String verifyRiskCodePeriod(AcceptRequestDataModel acceptRequestDataModel) {
        Date cvalidate = acceptRequestDataModel.getRequest().getPolicyInfo().getCvalidate();
        List<ProductModel> productListModel = acceptRequestDataModel.getRequest().getProductInfo().getProducts().getProduct();
        for (ProductModel productModel : productListModel) {
            String code = productModel.getProdCode();
            String area = (String) redisService.get(AcceptConstant.REDIS_PREFIX_R008 + code);
            try {
                String result = AcceptUtil.isTimeAreaString(area, cvalidate, code);
                if (!StringUtils.equals(AcceptConstant.RESULT_SUCCESS_CODE, result)) {
                    return result;
                }
            } catch (Exception e) {
                logger.error(e.getMessage());
                e.printStackTrace();
            }
        }
        return null;
    }

    private AcceptResponseDataModel messageStorageError(AcceptResponseDataModel acceptResponseDataModel,
                                                        AcceptRequestDataModel acceptRequestDataModel, long start) {
        MessageModel messageModel = InsuranceAcceptSupport.createMessageModel(acceptRequestDataModel, acceptResponseDataModel);
        messageModel.setUsedTime(System.currentTimeMillis() - start);
        try {
            if (StringUtils.equals(acceptResponseDataModel.getHeader().getResponseCode(), AcceptConstant.RESPONSE_ERROR_CODE)) {
                insuranceAcceptService.insertMessageError(messageModel);
            } else {
                insuranceAcceptService.insertMessage(messageModel);
            }
            return acceptResponseDataModel;
        } catch (Exception e) {
            logger.error("【" + acceptRequestDataModel.getRequest().getPolicyInfo().getContNo() + "】" + e.getMessage());
            insuranceAcceptService.insertMessageError(messageModel);
            if (e instanceof DuplicateKeyException) {
                return AcceptUtil.getDuplicateResponseResult(acceptRequestDataModel.getHeader());
            }
            return InsuranceAcceptSupport.bindingExceptionErrors(acceptRequestDataModel.getHeader());
        }
    }

    private AcceptResponseDataModel messageStorageSuccess(AcceptResponseDataModel acceptResponseDataModel,
                                                          AcceptRequestDataModel acceptRequestDataModel, long start) {

        BigDecimal enterPayPrem = acceptRequestDataModel.getRequest().getProductInfo().getSumPremL();
        BigDecimal systemPayPrem = new BigDecimal(acceptResponseDataModel.getResponse().getProductInfo().getPayPrem());
        //校验报文录入的保费和系统计算出的保费是否一致
        boolean flag = true;
        if (systemPayPrem.doubleValue() == enterPayPrem.doubleValue()) {
            PolicyModel policyModel = new PolicyModel();
            policyModel.setCustInfo(acceptRequestDataModel.getRequest().getCustInfo());
            policyModel.setPolicyInfo(acceptRequestDataModel.getRequest().getPolicyInfo());
            policyModel.setProductInfo(acceptRequestDataModel.getRequest().getProductInfo());
            RequestInfoModel request = new RequestInfoModel();
            request.setRequest(policyModel);
            logger.info("签单数据->" + JSONObject.toJSONString(request));
            //需要考虑超时时间设置 根据业务来决定  受理成功和签单的间隔时间
            String sb = AcceptConstant.REDIS_PREFIX_D003 + "|" + AcceptConstant.SERVICE_ACCEPT +
                    "|" + acceptRequestDataModel.getRequest().getPolicyInfo().getContNo();
            redisService.set(sb, JSONObject.toJSONString(request), 24, TimeUnit.HOURS);
        } else {
            flag = false;
            ResponseModel response = acceptResponseDataModel.getResponse();
            response.setProductInfo(null);
            response.getResult().setResultCode(AcceptConstant.RESULT_FAIL_CODE);
            response.getResult().setResultMessage(String.format(AcceptConstant.TRIAL_PREMIUM_MESSAGE, enterPayPrem, systemPayPrem));
        }
        MessageModel messageModel = InsuranceAcceptSupport.createMessageModel(acceptRequestDataModel, acceptResponseDataModel);
        messageModel.setUsedTime(System.currentTimeMillis() - start);
        messageModel.setPushFlag(flag ? 4 : 0);
        try {
            insuranceAcceptService.insertMessage(messageModel);
            if (AcceptConstant.RESULT_FAIL_CODE.equals(acceptResponseDataModel.getResponse().getResult().getResultCode())) {
                // 受理失败，删除Redis中的该保单的累计风险保额缓存
                redisService.delDim("*|" + acceptRequestDataModel.getRequest().getPolicyInfo().getContNo() + "|" + QuotaConstant.QUOTA);
                // 受理失败，删除Redis中的该保单的购买份数
                redisService.delDim("*|" + acceptRequestDataModel.getRequest().getPolicyInfo().getContNo() + "|" + "*|" + MultConstant.MULT);
            } else {
                // 受理成功，生产者生产消息
                // RabbitPolicyModel policyModel = new RabbitPolicyModel();
                // policyModel.setContno(acceptRequestDataModel.getRequest().getPolicyInfo().getContNo());
                // acceptProducerService.sendMessage(policyModel);
            }
            return acceptResponseDataModel;
        } catch (Exception e) {
            // 受理失败，删除Redis中的该保单的累计风险保额缓存
            redisService.delDim("*|" + acceptRequestDataModel.getRequest().getPolicyInfo().getContNo() + "|" + QuotaConstant.QUOTA);
            // 受理失败，删除Redis中的该保单的购买份数
            redisService.delDim("*|" + acceptRequestDataModel.getRequest().getPolicyInfo().getContNo() + "|" + "*|" + MultConstant.MULT);
            messageModel.setPushFlag(0);
            insuranceAcceptService.insertMessageError(messageModel);
            logger.error("【" + acceptRequestDataModel.getRequest().getPolicyInfo().getContNo() + "】" + e.getMessage());
            if (e instanceof DuplicateKeyException) {
                return AcceptUtil.getDuplicateResponseResult(acceptRequestDataModel.getHeader());
            }
            return InsuranceAcceptSupport.bindingExceptionErrors(acceptRequestDataModel.getHeader());
        }
    }

    private AcceptResponseDataModel isCustomerBlackList(CustInfoModel custInfoModel, RequestHeaderModel requestHeaderModel) {
        AcceptResponseDataModel acceptResponseDataModel = new AcceptResponseDataModel();
        acceptResponseDataModel.setFlag(true);
        String result = isBlackList(custInfoModel);
        if (StringUtils.equals(result, AcceptConstant.TASK_ERROR)) {
            logger.info("封装错误头");
            acceptResponseDataModel = InsuranceAcceptSupport.bindingExceptionErrors(requestHeaderModel);
            acceptResponseDataModel.setFlag(false);
            return acceptResponseDataModel;
            //封装错误头
        } else if (StringUtils.equals(result, AcceptConstant.TASK_TRUE)) {
            ResultModel resultModel = new ResultModel();
            resultModel.setResultCode(AcceptConstant.RESULT_FAIL_CODE);
            resultModel.setResultMessage(AcceptConstant.BLACK_LIST_SYSTEM_MESSAGE);
            acceptResponseDataModel = AcceptUtil.getResponseResult(requestHeaderModel, resultModel, null);
            acceptResponseDataModel.setFlag(AcceptConstant.TASK_FALSE);
        }
        return acceptResponseDataModel;
    }

    private String isBlackList(CustInfoModel custInfo) {
        HashSet<PersonModel> personModelList = InsuranceAcceptSupport.getPersonList(custInfo);
        List<Callable<TaskResponseModel>> baseTaskCallbackList = new ArrayList<>(personModelList.size());
        RequestObject requestObject;
        for (PersonModel personModel : personModelList) {
            requestObject = new RequestObject();
            requestObject.setParams(personModel);
            BlackCustomerCallBack blackCustomerCallBack = new BlackCustomerCallBack(AcceptConstant.TASK_IDENTITY_BLACKLIST,
                    requestObject, this.acceptBlackCustomerService);
            baseTaskCallbackList.add(blackCustomerCallBack);
        }
        long begin = System.currentTimeMillis();
        List<TaskResponseModel> taskResponseModelList = taskExecutor.execute(baseTaskCallbackList);
        for (TaskResponseModel data : taskResponseModelList) {
            if (StringUtils.equals(AcceptConstant.TASK_ERROR, data.getKey())) {
                return "error";
            }
        }
        for (TaskResponseModel data : taskResponseModelList) {
            if (StringUtils.equals(AcceptConstant.RESULT_FAIL_CODE, data.getResultCode())) {
                logger.info("【业务逻辑黑名单客户校验耗时】：" + (System.currentTimeMillis() - begin));
                return "true";
            }
        }
        return "false";
    }

    private AcceptResponseDataModel setCustomerNo(AcceptRequestDataModel acceptRequestDataModel) {
        AcceptResponseDataModel acceptResponseDataModel = new AcceptResponseDataModel();
        acceptResponseDataModel.setFlag(true);
        List<PersonModel> personCustomerNoList;
        HashSet<PersonModel> personModelList = InsuranceAcceptSupport.getPersonList(acceptRequestDataModel.getRequest().getCustInfo());
        try {
            personCustomerNoList = insuranceAcceptCoreService.getPersonCustomerNoList(personModelList);
            if (personCustomerNoList.stream().anyMatch(x -> StringUtils.equals(x.getRiskLevel(), DigitalConstant.STRING_NUMBER_THREE) ||
                    StringUtils.equals(x.getRiskLevel(), DigitalConstant.STRING_NUMBER_FOUR))) {
                ResultModel resultModel = new ResultModel(AcceptConstant.RESULT_FAIL_CODE, AcceptConstant.HIGH_RISK_CUSTOMER_MESSAGE);
                acceptResponseDataModel = AcceptUtil.getResponseResult(acceptRequestDataModel.getHeader(), resultModel, null);
                acceptResponseDataModel.setFlag(AcceptConstant.TASK_FALSE);
                return acceptResponseDataModel;
            }
        } catch (Exception exception) {
            logger.error("黑名单校验：" + acceptRequestDataModel.getRequest().getPolicyInfo().getContNo() + "; 错误信息：" + exception.getMessage());
            ResultModel resultModel = new ResultModel();
            resultModel.setResultCode(AcceptConstant.RESULT_FAIL_CODE);
            resultModel.setResultMessage(AcceptConstant.RESULT_FAIL_MESSAGE + "-黑名单校验");
            acceptResponseDataModel = AcceptUtil.getResponseResult(acceptRequestDataModel.getHeader(), resultModel, null);
            acceptResponseDataModel.setFlag(AcceptConstant.TASK_FALSE);
            return acceptResponseDataModel;
        }
        AppntModel appntModel = acceptRequestDataModel.getRequest().getCustInfo().getAppnt();
        List<InsurantModel> insurantModelList = acceptRequestDataModel.getRequest().getCustInfo().getInsurants().getInsurant();
        BnfInfoModel bnfInfo = acceptRequestDataModel.getRequest().getCustInfo().getBnfInfo();
        personCustomerNoList.stream().filter(p -> AcceptUtil.isSamePerson(appntModel, p)).findFirst().ifPresent(personModel -> {
            if (personModel.getCustomerNo() == null) {
                appntModel.setAppntNo("-1");
            } else {
                appntModel.setAppntNo(personModel.getCustomerNo());
            }
            appntModel.setBlackListFlag(personModel.getBlackListFlag());
            appntModel.setClaimFlag(personModel.getClaimFlag());
            appntModel.setIsWhite(personModel.getIsWhite());
            appntModel.setBrWhite(personModel.getBrWhite());
            appntModel.setSunWhite(personModel.getSunWhite());
        });
        for (InsurantModel insurantModel : insurantModelList) {
            personCustomerNoList.stream().filter(p -> AcceptUtil.isSamePerson(insurantModel, p)).findFirst().ifPresent(personModel -> {
                if (personModel.getCustomerNo() == null) {
                    insurantModel.setInsuredNo("-1");
                } else {
                    insurantModel.setInsuredNo(personModel.getCustomerNo());
                }
                insurantModel.setBlackListFlag(personModel.getBlackListFlag());
                insurantModel.setClaimFlag(personModel.getClaimFlag());
                insurantModel.setIsWhite(personModel.getIsWhite());
                insurantModel.setBrWhite(personModel.getBrWhite());
                insurantModel.setSunWhite(personModel.getBrWhite());
            });
        }
        if (StringUtils.equals(DigitalConstant.DESIGNATED, bnfInfo.getBnfType())) {
            for (BeneficiaryModel beneficiaryModel : bnfInfo.getBeneficiaries().getBeneficiary()) {
                personCustomerNoList.stream().filter(p -> AcceptUtil.isSamePerson(beneficiaryModel, p)).findFirst().ifPresent(personModel -> {
                    if (personModel.getCustomerNo() == null) {
                        beneficiaryModel.setBfcyNo("-1");
                    } else {
                        beneficiaryModel.setBfcyNo(personModel.getCustomerNo());
                    }
                });
            }
        }
        return acceptResponseDataModel;
    }

    /**
     * 判断保单中的产品渠道和代理机构的校验，是否在系统中支持以及是否存在主险
     *
     * @param productListModel       产品列表
     * @param acceptRequestDataModel 报文
     * @return AcceptResponseDataModel
     */
    private AcceptResponseDataModel hasSupportAndMainRisk(List<ProductModel> productListModel, AcceptRequestDataModel acceptRequestDataModel) {
        Object obj;
        boolean flag = false;
        String saleChnl = acceptRequestDataModel.getRequest().getPolicyInfo().getSaleChnl();
        if (StringUtils.equals(AcceptConstant.SALECHNL, saleChnl)) {
            obj = redisService.get(AcceptConstant.SALECHNL_KEY);
            List<?> agentComs;
            String agencyCode = acceptRequestDataModel.getRequest().getPolicyInfo().getAgencyCode();
            if (obj == null || (agentComs = (List<?>) obj).size() == 0) {
                flag = !StringUtils.equals("1", insuranceAcceptService.getAgentComByCode(agencyCode));
            } else {
                for (Object agentCom : agentComs) {
                    //是否存在有一agencyCode开始的  则退出
                    if (agencyCode.indexOf(String.valueOf(agentCom)) == 0) {
                        flag = false;
                        break;
                    }
                    flag = true;
                }
            }
        } else {
            flag = true;
        }
        AcceptResponseDataModel acceptResponseDataModel;
        RequestHeaderModel headerModel = acceptRequestDataModel.getHeader();
        if (flag) {
            ResultModel resultModel = new ResultModel();
            resultModel.setResultCode(AcceptConstant.RESULT_FAIL_CODE);
            resultModel.setResultMessage(AcceptConstant.SALECHNL_MESSAGE);
            acceptResponseDataModel = AcceptUtil.getResponseResult(headerModel, resultModel, null);
            acceptResponseDataModel.setFlag(Boolean.FALSE);
            return acceptResponseDataModel;
        }
        String param = "riskcode";
        List<String> riskCodeList = insuranceAcceptService.getRiskCodeList(param);

        for (ProductModel productModel : productListModel) {
            if (riskCodeList.contains(productModel.getProdCode())) {
                continue;
            }
            ResultModel resultModel = new ResultModel();
            resultModel.setResultCode(AcceptConstant.RESULT_FAIL_CODE);
            resultModel.setResultMessage(String.format(AcceptConstant.SYSTEM_NOT_PROUDCT_MESSAGE,
                    productModel.getProdCode(), productModel.getProdName()));
            acceptResponseDataModel = AcceptUtil.getResponseResult(headerModel, resultModel, null);
            acceptResponseDataModel.setFlag(Boolean.FALSE);
            return acceptResponseDataModel;
        }
        for (ProductModel productModel : productListModel) {
            param = AcceptConstant.REDIS_PREFIX_R004 + "|" + productModel.getProdCode();
            
            obj = redisService.get(param);
            if (obj != null) {
                if (obj.toString().endsWith(AcceptConstant.MAIN_RISK_FLAG)) {
                    acceptResponseDataModel = new AcceptResponseDataModel();
                    acceptResponseDataModel.setFlag(Boolean.TRUE);
                    return acceptResponseDataModel;
                }
            }
        }
        ResultModel resultModel = new ResultModel();
        resultModel.setResultCode(AcceptConstant.RESULT_FAIL_CODE);
        resultModel.setResultMessage(AcceptConstant.MAIN_RISK_MESSAGE);
        acceptResponseDataModel = AcceptUtil.getResponseResult(headerModel, resultModel, null);
        acceptResponseDataModel.setFlag(Boolean.FALSE);
        return acceptResponseDataModel;
    }

    /**
     * bankAccName、bankAccNo、bankCode 要么都为空，要么都有值
     *
     * @param productInfoModel 产品
     * @return Boolean
     */
    private Boolean checkProductBankInfo(ProductInfoModel productInfoModel) {
        if (StringUtils.isEmpty(productInfoModel.getBankAccName()) && StringUtils.isEmpty(productInfoModel.getBankAccNo()) && StringUtils.isEmpty(productInfoModel.getBankCode())) {
            return false;
        } else {
            return StringUtils.isEmpty(productInfoModel.getBankCode()) || StringUtils.isEmpty(productInfoModel.getBankAccNo()) || StringUtils.isEmpty(productInfoModel.getBankAccName());
        }
    }

    /**
     * 判处理效日取值
     *
     * @param request 请求报文
     */
    private void dealDate(RequestModel request) {
        String agencyCode = request.getPolicyInfo().getAgencyCode();
        if ((!StringUtils.equals(agencyCode, AcceptConstant.Z001) && !StringUtils.equals(agencyCode, AcceptConstant.V00105))
                && !this.isContainOneRiskCode(request.getProductInfo().getProducts(), AcceptConstant.PRODUCT_RISKCODE_AAT078)) {
            request.getPolicyInfo().setCvalidate(request.getPolicyInfo().getPolApplyDate());
        }
    }

    /**
     * 判断产品列表中是否包含指定险种
     *
     * @param productsModel 产品列表
     * @param riskCode      指定产品编码
     * @return true 包含
     */
    private boolean isContainOneRiskCode(ProductsModel productsModel, String riskCode) {
        for (ProductModel productModel : productsModel.getProduct()) {
            if (StringUtils.equals(productModel.getProdCode(), riskCode)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 处理普通校验可选参数的合法性
     *
     * @param request 请求
     * @return 响应
     */
    private ResultModel optionalCheck(RequestModel request) {
        // 校验BankAccName、BankCode、BankAccNo
        if (this.checkProductBankInfo(request.getProductInfo())) {
            return new ResultModel(AcceptConstant.RESULT_FAIL_CODE, AcceptConstant.BANK_INFORMATION_CHECK_CUSTOM_MESSAGE);
        }
        //校验生效日取值，非特殊渠道，将申请日赋值给生效日
        dealDate(request);
        //受益人校验如果是指定受益人必须填写受益人信息
        BnfInfoModel bnfInfo = request.getCustInfo().getBnfInfo();
        if (StringUtils.equals(DigitalConstant.DESIGNATED, bnfInfo.getBnfType())) {
            //指定受益人
            if (bnfInfo.getBeneficiaries() == null || CollectionUtils.isEmpty(bnfInfo.getBeneficiaries().getBeneficiary())) {
                return new ResultModel(AcceptConstant.RESULT_FAIL_CODE, "指定受益人信息不存在！");
            }
        }
        return null;
    }
}
